/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
/*
 * Topology Viewer
 */

package cgl.narada.topology.viewer;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;

//import com.ibm.ibmts.*;

class TopologyWindowAdapter extends WindowAdapter {
    public TopologyWindowAdapter() {
    }

    public void windowClosing(WindowEvent we) {
	System.exit(0);
    }  
}

/**
 * This class is the main class which initiates all the objects and is 
 * ressponsible for display of menu, buttons, execuation of menu actions etc.
 */
public class TopologyViewer extends JFrame 
    implements ActionListener, ComponentListener {
    public NodeManagement nodeManagement;
    public Screen screenPanel;
    public Simulation simulation;
    public Thread simulationThread;

    /**
     * Only constructor. Creates all the objects and initializes frame 
     * components. Starts the Simulation Thread at last.
     */
    public TopologyViewer() {
	super("Topology Viewer");
	nodeManagement = new NodeManagement();
	setBackground(Color.white);
	screenPanel = new Screen(nodeManagement);
	simulation = new Simulation(nodeManagement, screenPanel);
	simulationThread = new Thread(simulation);
	initializeAllComponents();
	nodeManagement.setZoomInFactor(2);
	nodeManagement.setZoomOutFactor(2);
	TopologyWindowAdapter adapter = new TopologyWindowAdapter();
	addWindowListener(adapter);
	addComponentListener(this);
	simulationThread.start();
    }

    /**
     * Adds three components of the frame. Menubar, main screen panel and lower
     * panel.
     */
    public void initializeAllComponents() {
	setSize(new Dimension(800, 600));
	setJMenuBar(getTopMenu());
	getContentPane().setLayout(new BorderLayout());
	getContentPane().add(screenPanel, BorderLayout.CENTER);
	getContentPane().add(screenPanel.getLowerScreenPanel(), 
			     BorderLayout.SOUTH);
    }

    /**
     * Returns complete menu bar 
     * @return <code>JMenuBar</code>
     */
    public JMenuBar getTopMenu() {
	JMenuBar topMenu = new JMenuBar();
	JMenu fileMenu = new JMenu("File");
	JMenuItem saveScreen = new JMenuItem("Save");
	JMenuItem printScreen = new JMenuItem("Print");
	JMenu navigationMenu = new JMenu("Navigation");
	JMenuItem zoomIn = new JMenuItem("Zoom In");
	JMenuItem zoomOut = new JMenuItem("Zoom Out");
	JMenuItem resetView = new JMenuItem("Reset View");
	JMenu zoomInFactor = new JMenu("Zoom In Factor");
	JMenuItem zoominfactor2 = new JMenuItem("2");
	JMenuItem zoominfactor3 = new JMenuItem("3");
	JMenuItem zoominfactor4 = new JMenuItem("4");
	JMenu zoomOutFactor = new JMenu("Zoom Out Factor");
	JMenuItem zoomoutfactor2 = new JMenuItem("2");
	JMenuItem zoomoutfactor3 = new JMenuItem("3");
	JMenuItem zoomoutfactor4 = new JMenuItem("4");

	JMenu infoMenu = new JMenu("Information");
	JMenuItem nodeInfo = new JMenuItem("See Node Information");
	JMenuItem linkInfo = new JMenuItem("See Link Information");
	JMenu helpMenu = new JMenu("Help");
	JMenuItem about = new JMenuItem("About");
	JMenuItem howToUse = new JMenuItem("How To Use");

	saveScreen.addActionListener(this);
	saveScreen.setActionCommand("save");
	saveScreen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
							 InputEvent.CTRL_MASK));
	printScreen.addActionListener(this);
	printScreen.setActionCommand("print");
	printScreen.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P,
							 InputEvent.CTRL_MASK));

	fileMenu.add(saveScreen);
	fileMenu.add(printScreen);
	
	zoomIn.addActionListener(this);
	zoomIn.setActionCommand("Zoom In");
	zoomIn.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I,
						     InputEvent.CTRL_MASK));

	zoomOut.addActionListener(this);
        zoomOut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,
						      InputEvent.CTRL_MASK));
	zoomOut.setActionCommand("Zoom Out");

	resetView.addActionListener(this);
	resetView.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R,
						      InputEvent.CTRL_MASK));
	resetView.setActionCommand("Reset View");
	
	zoominfactor2.addActionListener(this);
	zoominfactor2.setActionCommand("zoomin2");
	zoominfactor3.addActionListener(this);
	zoominfactor3.setActionCommand("zoomin3");
	zoominfactor4.addActionListener(this);
	zoominfactor4.setActionCommand("zoomin4");
	
	zoomInFactor.add(zoominfactor2);
	zoomInFactor.add(zoominfactor3);
	zoomInFactor.add(zoominfactor4);
	
	zoomoutfactor2.addActionListener(this);
	zoomoutfactor2.setActionCommand("zoomout2");
	zoomoutfactor3.addActionListener(this);
	zoomoutfactor3.setActionCommand("zoomout3");
	zoomoutfactor4.addActionListener(this);
	zoomoutfactor4.setActionCommand("zoomout4");
	
	zoomOutFactor.add(zoomoutfactor2);
	zoomOutFactor.add(zoomoutfactor3);
	zoomOutFactor.add(zoomoutfactor4);
	

	navigationMenu.add(zoomIn);
	navigationMenu.add(zoomOut);
	navigationMenu.add(resetView);
	navigationMenu.add(zoomInFactor);
	navigationMenu.add(zoomOutFactor);

	nodeInfo.addActionListener(this);
	nodeInfo.setActionCommand("nodeInfo");
	nodeInfo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
						     InputEvent.CTRL_MASK));

	linkInfo.addActionListener(this);
	linkInfo.setActionCommand("linkInfo");
        linkInfo.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L,
						      InputEvent.CTRL_MASK));
	infoMenu.add(nodeInfo);
	infoMenu.add(linkInfo);

	about.addActionListener(this);
	about.setActionCommand("about");
	howToUse.addActionListener(this);
	howToUse.setActionCommand("howToUse");

	helpMenu.add(about);
	helpMenu.add(howToUse);

	topMenu.add(fileMenu);
	topMenu.add(navigationMenu);
	topMenu.add(infoMenu);
	topMenu.add(helpMenu);
		
	topMenu.add(getToolBar());
	return topMenu;
    }

    /**
     * Returns complete tool bar. 
     */
    public JToolBar getToolBar() {
	JToolBar toolBar = new JToolBar();
	toolBar.setFloatable(false);
	JButton saveButton = new JButton(new 
					 ImageIcon("C:\\cgl\\narada\\"
						   + "topology\\viewer\\"
						   + "save.gif"));
	saveButton.addActionListener(this);
	saveButton.setActionCommand("save");
	toolBar.add(saveButton);
	toolBar.addSeparator();

	JButton zoomInButton = new JButton(new
					   ImageIcon("C:\\cgl\\narada\\"
						     + "topology\\viewer\\"
						     + "zoomin.gif"));
	zoomInButton.addActionListener(this);
	zoomInButton.setActionCommand("Zoom In");
	toolBar.add(zoomInButton);
	toolBar.addSeparator();

	JButton zoomOutButton = new JButton(new
					   ImageIcon("C:\\cgl\\narada\\"
						     + "topology\\viewer\\"
						     + "zoomout.gif"));
	zoomOutButton.addActionListener(this);
	zoomOutButton.setActionCommand("Zoom Out");
	toolBar.add(zoomOutButton);

	// following buttons are just for debugging purpose where you can
	// start or stop the Simulation thread.
	/*
	JButton stopButton = new JButton("STOP");
	stopButton.addActionListener(this);
	stopButton.setActionCommand("stop");
	toolBar.add(stopButton);

	JButton startButton = new JButton("START");
	startButton.addActionListener(this);
	startButton.setActionCommand("start");
	toolBar.add(startButton);
	*/

	return toolBar;
    }

    /**
     * Overriding method of ComponenetListener. Reverts to standard position
     * if screen is resized.
     */
    public void componentResized(ComponentEvent e) {
	screenPanel.setInitialPositions();
    }

    public void componentShown(ComponentEvent e) {
    }

    public void componentHidden(ComponentEvent e) {
    }

    public void componentMoved(ComponentEvent e) {
    }

    /**
     * Overriding method of ActionListener interface. handles all the action
     * events.
     * @param e <code>ActionEvent</code>
     */
    public void actionPerformed(ActionEvent e) {
	if (e.getActionCommand().equals("Zoom In")) {
	    nodeManagement.zoomIn(screenPanel.screenCenterX, 
				  screenPanel.screenCenterY);
	    screenPanel.display();
	} else if (e.getActionCommand().equals("Zoom Out")) {
	    nodeManagement.zoomOut(screenPanel.screenCenterX, 
				   screenPanel.screenCenterY);
	    screenPanel.display();
	} else if (e.getActionCommand().equals("Reset View")) {
	    screenPanel.setInitialPositions();
	    screenPanel.display();
	} else if (e.getActionCommand().equals("zoomin2")) {
	    nodeManagement.setZoomInFactor(2);
	} else if (e.getActionCommand().equals("zoomin3")) {
	    nodeManagement.setZoomInFactor(3);
	} else if (e.getActionCommand().equals("zoomin4")) {
	    nodeManagement.setZoomInFactor(4);
	} else if (e.getActionCommand().equals("zoomout2")) {
	    nodeManagement.setZoomOutFactor(2);
	} else if (e.getActionCommand().equals("zoomout3")) {
	    nodeManagement.setZoomOutFactor(3);
	} else if (e.getActionCommand().equals("zoomout4")) {
	    nodeManagement.setZoomOutFactor(4);
	} else if (e.getActionCommand().equals("nodeInfo")) {
	    screenPanel.mode = 1;
	} else if (e.getActionCommand().equals("linkInfo")) {
	    screenPanel.mode = 2;
	} else if (e.getActionCommand().equals("save")) {
	    try {
		screenPanel.saveScreen();
	    } catch (TopologyException te) {
		System.out.println("EXCEPTION");
		System.out.println(te.explanation);
	    }
	} else if (e.getActionCommand().equals("print")) {
	    try {
		screenPanel.printScreen();
	    } catch (TopologyException te) {
		System.out.println("EXCEPTION");
		System.out.println(te.explanation);
	    }
	} else if (e.getActionCommand().equals("about")) {
	    HelpFrame helpAbout = new HelpFrame("about");
	} else if (e.getActionCommand().equals("howToUse")) {
	    HelpFrame helpHowToUse = new HelpFrame("howToUse");
	} 
    }

    public static void main(String args[]) {
	new TopologyViewer().show();
    }
};
